package com.corpgovernment.organization.config;

import com.corpgovernment.api.supplier.vo.OtherOperatorTypeConfig;
import com.corpgovernment.common.apollo.OrganizationApollo;
import com.ctrip.corp.obt.generic.threadpool.core.spring.EnableDynamicTp;
import com.ctrip.corp.obt.generic.threadpool.core.support.DynamicTp;
import com.ctrip.corp.obt.generic.threadpool.core.support.ThreadPoolBuilder;
import com.ctrip.corp.obt.generic.threadpool.core.support.task.wrapper.TaskWrappers;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.google.common.collect.Sets;
import jodd.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.ctrip.corp.obt.generic.threadpool.common.em.QueueTypeEnum.ARRAY_BLOCKING_QUEUE;
@Configuration
//@EnableAsync
@Slf4j
@EnableDynamicTp
public class BeanConfig {

    private static final Integer MaxPoolSizeThreshold = 150;

    private static final long KEEP_ALIVE_TIME = 60L;

    @Autowired
    private OrganizationApollo organizationApollo;

    @Bean
    @DynamicTp("defaultThreadPoolExecutor")
    public ThreadPoolExecutor defaultThreadPoolExecutor() {

        int corePoolSize = 20;
        if (corePoolSize > MaxPoolSizeThreshold) {
            corePoolSize = MaxPoolSizeThreshold;
        }
        int maximumPoolSize = corePoolSize * 2;
        if (maximumPoolSize > MaxPoolSizeThreshold) {
            maximumPoolSize = MaxPoolSizeThreshold;
        }
        int threadQueueSize = 200;
        return ThreadPoolBuilder.newBuilder()
                .taskWrappers(TaskWrappers.getInstance().getByNames(Sets.newHashSet("ttl")))
                .corePoolSize(corePoolSize)
                .maximumPoolSize(maximumPoolSize)
                .keepAliveTime(1800L)
                .timeUnit(TimeUnit.SECONDS)
                .workQueue(ARRAY_BLOCKING_QUEUE.getName(), threadQueueSize)
                .rejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy())
                .build();
    }

    @Bean
    @DynamicTp("batchQueryThreadPoolExecutor")
    public ThreadPoolExecutor batchQueryThreadPoolExecutor() {

        int corePoolSize = 5;
        if (corePoolSize > MaxPoolSizeThreshold) {
            corePoolSize = MaxPoolSizeThreshold;
        }
        int maximumPoolSize = corePoolSize * 2;
        if (maximumPoolSize > MaxPoolSizeThreshold) {
            maximumPoolSize = MaxPoolSizeThreshold;
        }
        int threadQueueSize = 300;
        return ThreadPoolBuilder.newBuilder()
                .taskWrappers(TaskWrappers.getInstance().getByNames(Sets.newHashSet("ttl")))
                .corePoolSize(corePoolSize)
                .maximumPoolSize(maximumPoolSize)
                .keepAliveTime(1800L)
                .timeUnit(TimeUnit.SECONDS)
                .workQueue(ARRAY_BLOCKING_QUEUE.getName(), threadQueueSize)
                .rejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy())
                .build();
    }

    @Bean
    @DynamicTp("flushMenuThreadPoolExecutor")
    public ThreadPoolExecutor flushMenuThreadPoolExecutor() {

        int corePoolSize = 1;
        int maximumPoolSize = corePoolSize * 2;

        int threadQueueSize = 5;
        return ThreadPoolBuilder.newBuilder()
                .taskWrappers(TaskWrappers.getInstance().getByNames(Sets.newHashSet("ttl")))
                .corePoolSize(corePoolSize)
                .maximumPoolSize(maximumPoolSize)
                .keepAliveTime(1800L)
                .timeUnit(TimeUnit.SECONDS)
                .workQueue(ARRAY_BLOCKING_QUEUE.getName(), threadQueueSize)
                .rejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy())
                .build();
    }
    @Bean
    @DynamicTp("productSwitchQueryThreadPoolExecutor")
    public ThreadPoolExecutor productSwitchQueryThreadPoolExecutor() {

        int corePoolSize = 20;
        if (corePoolSize > MaxPoolSizeThreshold) {
            corePoolSize = MaxPoolSizeThreshold;
        }
        int maximumPoolSize = corePoolSize * 2;
        if (maximumPoolSize > MaxPoolSizeThreshold) {
            maximumPoolSize = MaxPoolSizeThreshold;
        }
        int threadQueueSize = 200;
        return ThreadPoolBuilder.newBuilder()
                .taskWrappers(TaskWrappers.getInstance().getByNames(Sets.newHashSet("ttl")))
                .corePoolSize(corePoolSize)
                .maximumPoolSize(maximumPoolSize)
                .keepAliveTime(1800L)
                .timeUnit(TimeUnit.SECONDS)
                .workQueue(ARRAY_BLOCKING_QUEUE.getName(), threadQueueSize)
                .rejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy())
                .build();
    }

    @Bean
    public OtherOperatorTypeConfig otherOperatorTypeConfig() {
        OtherOperatorTypeConfig otherOperatorTypeConfig = JsonUtils.parse(organizationApollo.getOtherOperatorType(), OtherOperatorTypeConfig.class);
        log.info("注入的其他操作类型：{}", JsonUtils.toJsonString(otherOperatorTypeConfig));
        return otherOperatorTypeConfig;
    }

    @Bean
    @DynamicTp("getValidPassengerThreadPoolExecutor")
    public ThreadPoolExecutor getValidPassengerThreadPoolExecutor() {

        int corePoolSize = 20;
        if (corePoolSize > MaxPoolSizeThreshold) {
            corePoolSize = MaxPoolSizeThreshold;
        }
        int maximumPoolSize = corePoolSize * 2;
        if (maximumPoolSize > MaxPoolSizeThreshold) {
            maximumPoolSize = MaxPoolSizeThreshold;
        }
        int threadQueueSize = 200;
        return ThreadPoolBuilder.newBuilder()
                .taskWrappers(TaskWrappers.getInstance().getByNames(Sets.newHashSet("ttl")))
                .corePoolSize(corePoolSize)
                .maximumPoolSize(maximumPoolSize)
                .keepAliveTime(1800L)
                .timeUnit(TimeUnit.SECONDS)
                .workQueue(ARRAY_BLOCKING_QUEUE.getName(), threadQueueSize)
                .rejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy())
                .build();
    }

}